<template>
	<view class="recorder">
	</view>
</template>

<script>
	export default {
		data() {
			return {
				isUserMedia: false,
				stream: null,
				audio: null,
				recorder: null,
				chunks: [],
				startTime: 0,
			}
		},
		mounted() {
			/**
			 * 	error 事件的返回状态
			 * 	100: 请在HTTPS环境中使用
			 * 	101: 浏览器不支持
			 *  201: 用户拒绝授权
			 *  500: 未知错误
			 * */
			if (origin.indexOf('https') === -1) {
				this.$emit('error', '需要https')
				throw '请在 https 环境中使用本插件。'
			}
			if (!navigator.mediaDevices || !window.MediaRecorder) {
				this.$emit('error', '当前浏览器不支持')
				throw '当前浏览器不支持'
			}
			// getRecorderManager
			if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator
				.mozGetUserMedia) {
				this.getUserMedia({
					audio: true
				}); // 调用用户媒体设备，访问摄像头、录音
			} else {
				uni.showToast({
					title: this.$t('chat.Device-unsupported'),
					icon: 'none'
				});
			}
		},
		methods: {
			getUserMedia(constrains) {
				this.audio = document.createElement('audio')
				let that = this;
				if (navigator.mediaDevices.getUserMedia) {
					// 最新标准API
					navigator.mediaDevices.getUserMedia(constrains).then(stream => {
						that.onSuccessHandler(stream);
					}).catch(err => {
						that.onErrorHandler(err);
					});
				} else if (navigator.webkitGetUserMedia) {
					// webkit内核浏览器
					navigator.webkitGetUserMedia(constrains).then(stream => {
						that.onSuccessHandler(stream);
					}).catch(err => {
						that.onErrorHandler(err);
					});
				} else if (navigator.mozGetUserMedia) {
					// Firefox浏览器
					navigator.mozGetUserMedia(constrains).then(stream => {
						that.onSuccessHandler(stream);
					}).catch(err => {
						that.onErrorHandler(err);
					});
				} else if (navigator.getUserMedia) {
					// 旧版API
					navigator.getUserMedia(constrains).then(stream => {
						that.onSuccessHandler(stream);
					}).catch(err => {
						that.onErrorHandler(err);
					});
				}
			},
			onSuccessHandler(stream, fn) {
				this.isUserMedia = true
				stream.getTracks().forEach((track) => {
					track.stop()
				})
				if (fn) fn()
			},
			// getRecorderManager(fn) {
			// 	this.audio = document.createElement('audio')
			// 	navigator.mediaDevices.getUserMedia({
			// 		audio: true
			// 	}).then(stream => {
			// 		this.isUserMedia = true
			// 		stream.getTracks().forEach((track) => {
			// 			track.stop()
			// 		})
			// 		if (fn) fn()
			// 	}).catch(err => {
			// 		this.onErrorHandler(err)
			// 	})
			// },
			start() {
				if (!this.isUserMedia) {
					this.getUserMedia({
						audio: true
					})
					this.$emit('error', '')
					return
				}
				this.chunks = []
				navigator.mediaDevices.getUserMedia({
					audio: true
				}).then(stream => {
					
					this.startTime = new Date().getTime()
					this.$emit('start')
					this.stream = stream
					this.recorder = new MediaRecorder(stream)
					this.recorder.ondataavailable = this.getRecordingData
					this.recorder.onstop = this.saveRecordingData
					this.recorder.start()
				}).catch(err => {
					this.onErrorHandler(err)
				})
			},
			stop() {
				try{
					console.log('stop', this.recorder)
					if (!this.recorder) return
					this.recorder.stop()
					this.stream.getTracks().forEach((track) => {
						track.stop()
					})
				}catch(e){
					console.log('暂停语音录制报错', e);
					//TODO handle the exception
				}
			},
			getRecordingData(e) {
				this.chunks = [e.data]
			},
			saveRecordingData() {
				const blob = new Blob(this.chunks, {
						'type': 'audio/mp3'
					}),
					localUrl = URL.createObjectURL(blob)

				const endTime = new Date().getTime()

				let duration = (endTime - this.startTime).toString().split('')
				duration.splice(duration.length - 2)
				duration.splice(duration.length - 1, 0, '.')
				duration = parseFloat(duration.join(''))

				const recorder = {
					data: blob,
					duration: duration,
					localUrl: localUrl
				}
				this.$emit('success', recorder)
			},
			onErrorHandler(err) {
				console.log(err, 'err');
				if (err.name === 'NotAllowedError') {
					this.$emit('error', this.$t('chat.Without-authorization'))
					throw '用户拒绝了当前的浏览器实例的访问请求'
				}

				if (err.name === 'NotReadableError') {
					this.$emit('error', this.$t('chat.Browser-not-supported'))
					throw '当前浏览器不支持'
				}

				this.$emit('error', this.$t('chat.Call-failed'))
				throw '调用失败，原因不详'

			}
		},
		destroyed() {
			this.stop()
		}
	}
</script>
<style>
</style>